package com.superbit.web.servlet.chat;

import java.io.IOException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;

import com.superbit.core.entry.tradelog.ChatLog;
import com.superbit.core.service.ChatLogService;
import com.superbit.utils.date.DateFormateUtils;
import com.superbit.web.listener.ServiceBeanFactory;

@ServerEndpoint("/chatServer.act")
public class ChatServer {
	private static Logger log = LoggerFactory.getLogger(ChatServer.class);

	// 存放每个客户端对应的ChatServer对象
	private static ConcurrentHashMap<Integer, Session> userSession = new ConcurrentHashMap<Integer, Session>();

	private Integer userId;

	private ChatLogService chatLogService;

	/**
	 * 连接建立成功调用的方法
	 * 
	 * @param session
	 *            可选的参数。session为与某个客户端的连接会话，需要通过它来给客户端发送数据
	 */
	@OnOpen
	public void onOpen(Session session) {
		if (chatLogService == null) {
			chatLogService = ServiceBeanFactory.getBean(ChatLogService.class);
		}
		// 格式为userId=111&orderNumber=222
		String queryString = session.getQueryString();
		log.info("ChatWebSocketServer.onOpen() queryString:{}", queryString);
		if (StringUtils.isBlank(queryString)) {
			return;
		}

		String[] params = StringUtils.split(queryString, "&");
		Map<String, String> map = new HashMap<String, String>(0);
		for (int i = 0; i < params.length; i++) {
			String[] p = params[i].split("=");
			if (p.length == 2) {
				map.put(p[0], String.valueOf(p[1]));
			}
		}

		this.userId = Integer.parseInt(map.get("userId"));
		userSession.put(userId, session);

		// 返回历史聊天记录
		String orderNumber = map.get("orderNumber");
		List<ChatLog> chatLogs = this.chatLogService
				.getChatLogByOrderNumber(orderNumber);
		if (CollectionUtils.isNotEmpty(chatLogs)) {
			// 转换为发送对象列表
			List<ChatMessage> retList = new ArrayList<ChatMessage>();
			List<String> orderNumbers = new ArrayList<String>();
			for (ChatLog chatLog : chatLogs) {
				ChatMessage chatMessage = new ChatMessage();
				BeanUtils.copyProperties(chatLog, chatMessage);
				chatMessage.setSendMessageTime(DateFormateUtils.formate(chatLog
						.getCreateTime()));
				retList.add(chatMessage);
				orderNumbers.add(chatLog.getOrderNumber());
			}

			// 发消息
			this.sendMessage(session, retList);
			// 更新为已读
			this.chatLogService.updateHasRead(orderNumbers);
		}
	}

	/**
	 * 连接关闭调用的方法
	 */
	@OnClose
	public void onClose() {
		userSession.remove(this.userId);
		log.info("ChatWebSocketServer.onClose() remove userId:{}", userId);
	}

	/**
	 * 收到客户端消息后调用的方法
	 * 
	 * @param message
	 *            客户端发送过来的消息
	 * @param session
	 *            可选的参数
	 */
	@OnMessage
	public void onMessage(String message, Session session) {
		log.info("ChatWebSocketServer.onMessage() receive message:{}", message);

		JSONObject json = JSONObject.fromObject(message);
		ChatMessage chatMessage = (ChatMessage) JSONObject.toBean(json,
				ChatMessage.class);
		if (chatMessage != null) {
			// 保存消息
			ChatLog chatLog = new ChatLog();
			BeanUtils.copyProperties(chatMessage, chatLog);
			chatLog.setCreateTime(new Timestamp(System.currentTimeMillis()));
			this.chatLogService.saveChatLog(chatLog);

			// 发送消息
			Session toSession = userSession.get(chatMessage.getToUid());
			chatMessage.setSendMessageTime(DateFormateUtils.formate(chatLog
					.getCreateTime()));
			this.sendMessage(toSession, chatMessage);

			// 更新为已读
			this.chatLogService.updateHasRead(Arrays.asList(chatMessage
					.getOrderNumber()));
		}
	}

	/**
	 * 发生错误时调用
	 * 
	 * @param session
	 * @param error
	 */
	@OnError
	public void onError(Session session, Throwable error) {
		log.error("ChatWebSocketServer.onError() exception", error);
	}

	/**
	 * 发消息
	 */
	public void sendMessage(Session session, String message) {
		if (session != null && StringUtils.isNotBlank(message)) {
			try {
				// session.getAsyncRemote().sendText(message);
				session.getBasicRemote().sendText(message);
			} catch (IOException e) {
				log.error("ChatWebSocketServer.sendMessage() exception", e);
			}
		}
	}

	/**
	 * 发消息
	 */
	public void sendMessage(Session session, List<ChatMessage> chatMessage) {
		if (CollectionUtils.isNotEmpty(chatMessage)) {
			JSONArray json = JSONArray.fromObject(chatMessage);
			String message = json.toString();
			this.sendMessage(session, message);
		}
	}

	/**
	 * 发消息
	 */
	public void sendMessage(Session session, ChatMessage chatMessage) {
		if (chatMessage != null) {
			List<ChatMessage> messageList = new ArrayList<ChatMessage>();
			messageList.add(chatMessage);
			this.sendMessage(session, messageList);
		}
	}
}
